`include "../define.svh"

module Mult_special_case (
    input [1:0] data_type,
    input [7:0] e1,
    input [7:0] e2,
    //input s1, s2,
    input [22:0] m1,
    input [22:0] m2,
    output [7:0] e_out,
    output [22:0] m_out,
    //output output_sign,
    output spec_valid
);

    // 浮点类型判断
    wire is_fp16;
    assign is_fp16 = (data_type == 2'b10);
    wire is_fp32;
    assign is_fp32 = (data_type == 2'b11);

    // 操作数1的Inf/NaN/Zero检测
    wire fp16_inf_1;
    assign fp16_inf_1= (e1 == `FP16_INF_EXP);
    wire fp32_inf_1;
    assign fp32_inf_1 = (e1 == `FP32_INF_EXP);
    wire m_zero_1;
    assign m_zero_1 = (is_fp16) ? (m1[9:0] == 0) : (m1 == 0);
    wire op1_inf;
    assign op1_inf = (is_fp16 && fp16_inf_1 && m_zero_1) || (is_fp32 && fp32_inf_1 && m_zero_1);
    wire op1_nan;
    assign op1_nan = (is_fp16 && fp16_inf_1 && !m_zero_1) || (is_fp32 && fp32_inf_1 && !m_zero_1);

    // 操作数2的Inf/NaN/Zero检测
    wire fp16_inf_2;
    assign fp16_inf_2 = (e2 == `FP16_INF_EXP);
    wire fp32_inf_2;
    assign fp32_inf_2 = (e2 == `FP32_INF_EXP);
    wire m_zero_2;
    assign m_zero_2 = (is_fp16) ? (m2[9:0] == 0) : (m2 == 0);
    wire op2_inf;
    assign op2_inf = (is_fp16 && fp16_inf_2 && m_zero_2) || (is_fp32 && fp32_inf_2 && m_zero_2);
    wire op2_nan;
    assign op2_nan = (is_fp16 && fp16_inf_2 && !m_zero_2) || (is_fp32 && fp32_inf_2 && !m_zero_2);

    // 零检测
    wire op1_zero;
    assign op1_zero = (e1 == 0) && m_zero_1;
    wire op2_zero;
    assign op2_zero = (e2 == 0) && m_zero_2;

    // 特殊场景标志
    wire any_nan, zero_inf, both_inf, is_nan, is_inf, is_zero;
    assign any_nan = op1_nan || op2_nan;
    assign zero_inf = (op1_zero && op2_inf) || (op2_zero && op1_inf);
    assign both_inf = op1_inf && op2_inf;
    assign is_nan = any_nan || zero_inf;
    assign is_inf = (op1_inf || op2_inf) && !any_nan;
    assign is_zero = (op1_zero || op2_zero) && !zero_inf;

    // 符号位统一异或
    //assign output_sign = s1 ^ s2;

    // 指数与尾数赋值
    assign e_out = (is_nan || is_inf) ? 8'hFF : 
                  (is_zero) ? 8'd0 : 8'd0;
    assign m_out = is_nan ? 23'b1000_0000_0000_0100_0000_000 : 
                  (is_zero) ? 23'd0 : 23'd0;

    // 非法类型检查（非浮点模式下出现Inf/NaN）
    //wire illegal_type = (data_type != 2'b10 && data_type != 2'b11) && 
    //                   (op1_nan || op1_inf || op2_nan || op2_inf);
    //assign spec_valid = (is_nan || is_inf) && !illegal_type;
    assign spec_valid = (is_nan || is_inf || is_zero);

endmodule